package com.zb.security.interceptor;

import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.log4j.Logger;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.zb.common.annotation.Permission;
import com.zb.common.po.enums.ResponseCode;
import com.zb.common.po.model.Menu;
import com.zb.common.po.model.SessionUser;
import com.zb.common.po.vo.AjaxResponse;
import com.zb.common.utils.Constants;
import com.zb.common.utils.JacksonMapper;

public class AuthInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = Logger
            .getLogger(AuthInterceptor.class);

    /**
     * 权限控制
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        // 验证是否具有权限
        if (!validate(request, handler)) {
            if (request.getHeader("x-requested-with") != null
                    && request.getHeader("x-requested-with").equalsIgnoreCase(
                            "XMLHttpRequest")) { // ajax请求
                response.setHeader("Content-Type", "text/html;charset=UTF-8");
                PrintWriter writer = response.getWriter();
                AjaxResponse<?> ajaxResponse = new AjaxResponse<Object>();
                ajaxResponse.setResponseCode(ResponseCode.NOPERMISSION);
                ajaxResponse.setErrorMsg("你没有操作权限！");
                writer.print(JacksonMapper.toJson(ajaxResponse));
            } else {
                response.sendRedirect(request.getContextPath()
                        + "/page/error/403.html");
            }
            return false;
        }
        return true;
    }

    /**
     * 校验用户是否拥有权限
     * 
     * @param request
     * @param permission
     * @return
     */
    private boolean validate(HttpServletRequest request, Object handler) {
        if (null == handler) {
            return false;
        }
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        // 处理Permission Annotation，实现方法级权限控制
        HandlerMethod method = (HandlerMethod) handler;
        Permission permission = method.getMethodAnnotation(Permission.class);
        // 如果为空在表示该方法不需要进行权限验证
        if (permission == null) {
            return true;
        }
        SessionUser sessionUser = (SessionUser) request.getSession()
                .getAttribute(Constants.SESSION_KEY);

        /**
         * 
         * 这里是演示平台，让测试账号可以看到所有权限，但是限制保存，修改，删除等操作，下载源码了的可以把这一段去掉
         * 
         */
        String url = request.getRequestURI();
        int last_param = url.lastIndexOf("?");
        url = url.substring(url.lastIndexOf("/") + 1,
                last_param == -1 ? url.length() : last_param);
        String testRole = "2";
        String[] noPermMenus = { "save_menue.do", "del_menue.do",
                "role_add.do", "role_update.do", "delRole.do", "user_add.do",
                "user_update.do", "user_disable.do", "user_enable.do",
                "user_delete.do", "task_add.do", "task_edit.do",
                "task_suspended.do", "task_enable.do",
                "immediate_execution.do", "task_del.do" };
        String[] roleArray = sessionUser.getRole().split(",");
        if (ArrayUtils.contains(roleArray, testRole)
                && ArrayUtils.contains(noPermMenus, url)) {// 是测试账号，那么过滤相关权限
            return false;
        }
        /**
         * 测试账号限制结束
         */
        List<Menu> menus = sessionUser.getMenuList();
        for (Menu menu : menus) {
            String code = menu.getPermissionCode();
            if (null != code && code.equals(permission.code())) {
                return true;
            }
        }
        return false;
    }
}